#include "server.h"
#include <unistd.h>


Server::Server(QObject *parent) :
    QTcpServer(parent),
    pgen(this),
    _port(0),
    connections_locked(false)
{

}


Server::~Server()
{
    this->close();
}



void Server::connections_lock()
{
    connections_locked = true;
}


void Server::connections_unlock()
{
    connections_locked = false;
}


/* Нужно побырику всех отключить */
void Server::abort(bool wait)
{
    this->close();

    QList <IpConnection *> ilist = c_database.clients();

    foreach(IpConnection *ic, ilist) {
        qWarning() << "Aborting " << ic->_ip;
        ic->abort(wait);
    }
}


void Server::force_abort()
{
    this->close();

    QList <IpConnection *> ilist = c_database.clients();

    foreach(IpConnection *ic, ilist) {
        ic->forceAbort(false);
    }
}


int Server::init_host(QHostAddress address, int port)
{
    this->close();

    if (!this->listen(address, port)) {
        emit log(QString("Unable to start the server: %1").arg(this->errorString()), 0xFFFF0000);
        return -1;
    } else {
        emit log(QString("TCPSocket listen on port %1").arg(port), 0xFF00FF00);
        _ip = address.toString();
        _port = port;
    }
    return 0;
}


void Server::emitLog(const QString & msg, uint color)
{
    emit log(msg, color);
}


int Server::stop()
{
    _ip.clear();
    _port = 0;
    emit log("Server stoped", 0xFFFF0000);
    this->close();
    this->abort(false);
    return 0;
}


const QString & Server::ip() const
{
    return _ip;
}


int Server::port() const
{
    return _port;
}


void Server::incomingConnection(int handle)
{
    if(!connections_locked)
        startClientServerDialog(handle);
}


void Server::startClientServerDialog( int handle )
{
    ClientThread *c_thread = new ClientThread(this, handle);

    connect(c_thread, SIGNAL(clientThreadCreated(ClientThread *)), this, SLOT(clientHasBeenConnected(ClientThread *)));
    connect(c_thread, SIGNAL(clientThreadDestroyed(ClientThread *)), this, SLOT(clientHasBeenDisconected(ClientThread *)));

    c_thread->dialog();
}


void Server::clientHasBeenConnected(ClientThread *t)
{
    mutex.lock();
    c_database.registerClientThread(t);
    emit log(QString(" [+] New connection %1").arg( t->ip() ));
    emit clientConnected(t);
    mutex.unlock();
}




void thread_del(ClientThread *cl) {
    cl->waitForFinished();
    delete cl;
}


void Server::clientHasBeenDisconected(ClientThread *self)
{
    mutex.lock();
    qWarning() << __FUNCTION__ << self->ip();

    emit UpdateBar();
    qWarning() << "UpdateBar";

    /* delete it from clients base */
    c_database.removeClientThread(self);

    qWarning() << "removeClientThread";

    emit clientDisconected(self->ip());

    qWarning() << __FUNCTION__ << "Trying kill ...";
    scheduler.schedule((void*)thread_del, self);
    mutex.unlock();
}
